package cn.itcast.web.controller.cargo;

import cn.itcast.domain.cargo.*;
import cn.itcast.domain.cargo.Export;
import cn.itcast.domain.cargo.ExportExample;
import cn.itcast.service.cargo.ContractService;
import cn.itcast.service.cargo.ExportProductService;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductVo;
import cn.itcast.vo.ExportResult;
import cn.itcast.vo.ExportVo;
import cn.itcast.web.controller.system.BaseController;
import cn.itcast.web.utils.BeanMapUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.*;

@Controller
@RequestMapping("/cargo/export")
public class ExportController extends BaseController {

  @Reference
  private ExportService exportService;

  @Reference
  private ContractService contractService;

  @Reference
  private ExportProductService exportProductService;

  @Autowired
  private DataSource dataSource;

  /*
    url: /cargo/export/contractList.do
    作用： 进入合同管理页面
    参数： 无
    返回值：合同管理页面
   */
  @RequestMapping("/contractList")
  public String contractList(@RequestParam(defaultValue = "1") int pageNum,
                             @RequestParam(defaultValue = "5") int pageSize) {
    ContractExample contractExample = new ContractExample();
    contractExample.setOrderByClause("create_time desc");
    contractExample.createCriteria().andStateEqualTo(1).andCompanyIdEqualTo(getLoginCompanyId());
    PageInfo<Contract> pageInfo = contractService.findByPage(contractExample, pageNum, pageSize);
    request.setAttribute("pageInfo", pageInfo);
    return "cargo/export/export-contractList";
  }

  /*
  url: /cargo/export/list.do
  作用： 报运单列表
  参数： 无
  返回值：报运单列表
 */
  @RequestMapping("/list")
  public String list(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "5") int pageSize) {
    ExportExample exportExample = new ExportExample();
    exportExample.setOrderByClause("create_time desc");
    exportExample.createCriteria().andCompanyIdEqualTo(getLoginCompanyId());
    PageInfo<Export> pageInfo = exportService.findByPage(exportExample, pageNum, pageSize);
    request.setAttribute("pageInfo", pageInfo);
    return "cargo/export/export-list";
  }

  /*
 url: /cargo/export/toExport.do
 作用： 进入生成报运单页面
 参数： 多个报运单的id
 返回值：生成报运单页面
*/
  @RequestMapping("/toExport")
  public String toExport(String id) { //1,2,3
    request.setAttribute("id", id);
    return "cargo/export/export-toExport";
  }

  /*
  url: cargo/export/edit.do
  作用： 新增报运单||更新报运单
  参数： 报运单
  返回值：报运单列表页面
 */
  @RequestMapping("/edit")
  public String edit(Export export) {
    //补全报运单信息
    String companyId = getLoginCompanyId();
    String companyName = getLoginCompanyName();
    export.setCompanyId(companyId);
    export.setCompanyName(companyName);
    //补全购销创建人与创建人所属的报运单
    export.setCreateBy(getLoginUser().getId()); //登陆者的id
    export.setCreateDept(getLoginUser().getDeptId()); //登陆者所属的报运单

    if (StringUtils.isEmpty(export.getId())) {
      exportService.save(export);
    } else {
      exportService.update(export);
    }
    return "redirect:/cargo/export/list.do";  //添加redirect开头的返回值则不会经过视图解析器
  }

  /*
 url: /cargo/export/toUpdate.do?id=5a3680c7-c3eb-4e22-a8f1-f733fb4f1a9e
 作用： 进入报运单的修改页面
 参数： 报运单的id
 返回值：报运单的修改页面
*/
  @RequestMapping("/toUpdate")
  public String toUpdate(String id) {
    //1. 查找到对应的报运单
    Export export = exportService.findById(id);
    request.setAttribute("export", export);

    //2 查找报运单对应的货物数据
    ExportProductExample exportProductExample = new ExportProductExample();
    exportProductExample.createCriteria().andExportIdEqualTo(id);
    List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);
    request.setAttribute("eps", exportProductList);

    return "cargo/export/export-update";
  }

  /*
    url: /cargo/export/delete.do?id=f79205a7-4fe8-4792-9d69-9f8bcb417a0c
    作用： 删除运单
    参数： 报运单的id
    返回值：报运单的展示页面
   */
  @RequestMapping("/delete")
  public String delete(String id) {
    exportService.delete(id);
    return "redirect:/cargo/export/list.do";
  }

  /*
        作用: 根据报运单id查看报运单
        url ： /cargo/export/toView.do?id=804d7e6c-4eeb-4826-9a8c-8c389fe7a786
        参数： id  报运单的id
        返回： 报运单详情页面
 */
  @RequestMapping("/toView")
  public String toView(String id) {
    Export export = exportService.findById(id);
    request.setAttribute("export", export);
    return "cargo/export/export-view";
  }

  /*
      作用: 提交报运单
      url ： /cargo/export/submit.do?id=804d7e6c-4eeb-4826-9a8c-8c389fe7a786
      参数： id  报运单的id
      返回： 返回报运单列表
*/
  @RequestMapping("/submit")
  public String submit(String id) {
    Export export = exportService.findById(id);
    export.setState(1);
    exportService.update(export);
    return "redirect:/cargo/export/list.do";
  }

  /*
     作用: 取消提交报运单
     url ： /cargo/export/cancel.do?id=804d7e6c-4eeb-4826-9a8c-8c389fe7a786
     参数： id  报运单的id
     返回： 返回报运单列表
*/
  @RequestMapping("/cancel")
  public String cancel(String id) {
    Export export = exportService.findById(id);
    export.setState(0);
    exportService.update(export);
    return "redirect:/cargo/export/list.do";
  }

  /*
作用: 电子报运
url ： /cargo/export/exportE.do?id=804d7e6c-4eeb-4826-9a8c-8c389fe7a786
参数： id  报运单的id
返回： 返回报运单列表
*/
  @RequestMapping("/exportE")
  public String exportE(String id) {
    //1. 根据id查找报运单
    Export export = exportService.findById(id);
    //2. 由于海关不接受你的Export，只接受ExportVo对象,所以你需要把Export的数据转换为ExportVo对象.
    ExportVo exportVo = new ExportVo();
    BeanUtils.copyProperties(export, exportVo);
    //该报运的信息所属报运单
    exportVo.setExportId(export.getId());

    //3.查找该报运单的商品，然后把商品信息封装到ExportProductVo对象，然后把ExportProductVo对象添加ExportVo对象中
    ExportProductExample exportProductExample = new ExportProductExample();
    exportProductExample.createCriteria().andExportIdEqualTo(id);
    List<ExportProduct> exportProductList = exportProductService.findAll(exportProductExample);
    for (ExportProduct exportProduct : exportProductList) {
      //一个报运单商品就是一个ExportProductVo对象
      ExportProductVo exportProductVo = new ExportProductVo();
      BeanUtils.copyProperties(exportProduct, exportProductVo);
      //设置所属的报运单
      exportProductVo.setExportId(export.getId());
      //所属报运商品的id
      exportProductVo.setExportProductId(exportProduct.getId());
      //报运的商品添加到报运单的Vo
      exportVo.getProducts().add(exportProductVo);
    }

    //4. 调用海关平台提交报运单的方法
    WebClient.create("http://localhost:9090/ws/export/user").post(exportVo);

    //5. 查看报运单审核的状态
    ExportResult exportResult =
        WebClient.create("http://localhost:9090/ws/export/user/" + export.getId()).get(ExportResult.class);

    //6. 更新本地的报运单的信息（状态，商品税）
    exportService.updateExport(exportResult);

    return "redirect:/cargo/export/list.do";
  }

  /*
    作用: 下载报运单
    url ： /cargo/export/exportPdf.do?id=4028d3cf567275410156735276210001
    参数： id  报运单的id
    返回： 无返回，因为最后要是要下载
*/
  @RequestMapping("/exportPdf")
  @ResponseBody
  public void exportPdf(String id) throws Exception {
    //1. 读取到jasper的文件的输入流
    InputStream inputStream = session.getServletContext().getResourceAsStream("/jasper/export.jasper");
    //2. 使用jasper文件输入流与数据结合，形参一个jasperPrint对象
        /*
            fillReport() , 把数据和jasperPrint对象结合形参一个jasperPrint对象
                参数一： japser文件的输入流
                参数二： 填充参数， 这里的参数是不需要遍历
                参数三： 需要遍历数据
         */
   /* Map<String, Object> map = new HashMap<>();
    map.put("username", "王总");
    map.put("email", "wangzong@163.com");
    map.put("companyName", "传智播客");
    map.put("deptName", "总裁办");*/

    //    模拟从数据库中查找到的数据
   /* List<Map<String,Object>> list = new ArrayList<>();
    Random random  = new Random();
    for (int i = 1; i <= 4; i++) {
      //每一份数据就是一个Map，一个Map需要包含title， value两个值
      Map<String,Object> map = new HashMap<>();
      map.put("title","标题"+i);
      map.put("value",random.nextInt(100));
      list.add(map);
    }*/
    //2.1 找到报运单
    Export export = exportService.findById(id);
    // 2.2 把报运单的对象转换为map  spring 提供了一个工具给我们把对象转换为Map
    Map<String, Object> map = BeanMapUtils.beanToMap(export);
    //2.3 找到报运单下的商品
    ExportProductExample exportProductExample = new ExportProductExample();
    exportProductExample.createCriteria().andExportIdEqualTo(id);
    List<ExportProduct> list = exportProductService.findAll(exportProductExample);

    //把list集合数据交给模板
    JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream, map,
        new JRBeanCollectionDataSource(list));
    //通知浏览器以附件的形式处理数据的内容即可,并且加上@ResponseBody注解！！！！！！！！！！！！！
    response.setHeader("content-disposition", "attachement;filename=export.pdf");
    //3. 把jasperPrint对象输出，产生一个pdf文件
    JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());
  }
}
